import pygame

class BlockMover:
    """处理方块的移动和碰撞检测逻辑"""
    def __init__(self, block):
        """初始化移动器
        参数:
            block: 要移动的方块对象
        """
        self.block = block

    def move(self, direction, number_blocks):
        """移动方块并处理碰撞

        参数:
            direction (str): 移动方向 ('up', 'down', 'left', 'right')
            number_blocks (list): 所有数字方块列表
        返回:
            bool: 是否成功移动
        """
        # 玩家方块始终可以移动
        if not (self.block.movable or self.block.is_player):
            return False

        # 计算新位置
        new_row, new_col = self.block.row, self.block.col
        if direction == 'up':
            new_row = max(0, new_row - 1)
        elif direction == 'down':
            new_row = min(self.block.grid_height - 1, new_row + 1)
        elif direction == 'left':
            new_col = max(0, new_col - 1)
        elif direction == 'right':
            new_col = min(self.block.grid_width - 1, new_col + 1)



        # 检查新位置是否有碰撞
        can_move = True
        for block in number_blocks:
            if block != self.block and block.row == new_row and block.col == new_col:
                if ((self.block.type == "number" and (block.type == "operator" or block.type == "equal")) or \
                   ( (self.block.type == "operator" or self.block.type == "equal") and block.type == "number")) and self.block.to_merge:
                    if not (self.block.is_player or block.is_player) and not block.just_merged:
                        can_move = False
                    elif self.block.is_player and not block.is_player and not block.just_merged:
                        can_move = True
                    break
                elif not self.block.to_merge:
                    if block.type == "equal":
                        can_move = True
                    else:
                        can_move = False
                    break
                else:
                    can_move = False
                    break

        # 只有可以移动时才更新位置
        if can_move:
            self.block.row, self.block.col = new_row, new_col
            return True
        return False

class BlockRenderer:
    """处理方块的渲染逻辑"""
    def __init__(self, block):
        """初始化渲染器
        参数:
            block: 要渲染的方块对象
        """
        self.block = block

    def _render_block(self, screen, x, y, block_size, bg_color, text_color, display_text):
        """公共渲染方法

        参数:
            screen: pygame显示surface
            x: 方块左上角x坐标
            y: 方块左上角y坐标
            block_size: 方块大小
            bg_color: 背景颜色
            text_color: 文本颜色
            display_text: 要显示的文本
        """
        pygame.draw.rect(screen, bg_color, (x, y, block_size, block_size))
        text_x = x + block_size // 2
        text_y = y + block_size // 2
        text_surface = self.block.font.render(display_text, True, text_color)
        text_rect = text_surface.get_rect(center=(text_x, text_y))
        screen.blit(text_surface, text_rect)

    def render(self, screen, offset_x=0, offset_y=0):
        """渲染方块到指定surface

        参数:
            screen: pygame显示surface
            offset_x: 网格在屏幕上的x偏移(默认0)
            offset_y: 网格在屏幕上的y偏移(默认0)
        """
        block_size = self.block.cell_size * 0.8
        x = offset_x + self.block.col * self.block.cell_size + (self.block.cell_size - block_size) // 2
        y = offset_y + self.block.row * self.block.cell_size + (self.block.cell_size - block_size) // 2

        # 设置默认显示文本和背景颜色
        bg_color = (255, 255, 255)
        display_text = ""

        if self.block.type == "operator" or self.block.type == "equal":
            bg_color = (255, 255, 0) if (self.block.is_player and self.block.movable) else self.block.color
            display_text = str(self.block.operator)
        else:
            bg_color = (255, 255, 0) if (self.block.is_player and self.block.movable) else (255, 255, 255)
            display_text = str(self.block.value)

        self._render_block(screen, x, y, block_size, bg_color, (0, 0, 0), display_text)


class NumberBlock:
    def __init__(self, value=0, row=0, col=0, cell_size=50, font=None, grid_width=10, grid_height=10,
                 is_player=False, movable=False, just_merged=False, to_merge=True, block_type="number",
                 operator="", game=None):
        """初始化方块(支持数字和运算符)

        参数:
            value (int): 方块显示的数字(运算符时为0)
            row (int): 所在行(网格坐标)
            col (int): 所在列(网格坐标)
            cell_size (int): 单元格大小(像素)
            font: pygame字体对象
            grid_width (int): 网格宽度(默认10)
            grid_height (int): 网格高度(默认10)
            is_player (bool): 是否是玩家控制的方块(默认False)
            movable (bool): 方块是否可以移动(默认False)
            just_merged (bool): 是否刚合并的方块(默认False)
            block_type (str): 方块类型("number"或"operator")
            operator (str): 运算符符号(可选)
            game: 游戏主实例(可选)
        """
        self.game = game
        self.value = value
        self.type = block_type
        self.row = row
        self.col = col
        self.cell_size = cell_size
        self.font = font
        self.grid_width = grid_width
        self.grid_height = grid_height
        self.is_player = is_player
        self.movable = movable
        self.just_merged = just_merged
        self.to_merge = to_merge
        self.operator = operator
        self.color = (173, 216, 230) if block_type == "operator" or block_type == "equal" else (255, 255, 255)
        self.mover = BlockMover(self)
        self.renderer = BlockRenderer(self)
        self.update_rect()

    def update_rect(self):
        """更新方块的矩形位置"""
        self.rect = pygame.Rect(
            self.col * self.cell_size,
            self.row * self.cell_size,
            self.cell_size,
            self.cell_size
        )

    def move(self, direction, number_blocks):
        """移动数字方块(委托给BlockMover处理)"""
        return self.mover.move(direction, number_blocks)

    def render(self, screen, offset_x=0, offset_y=0):
        """渲染数字方块(委托给BlockRenderer处理)"""
        self.renderer.render(screen, offset_x, offset_y)